#include "MCPoint2D.h"
#include <cmath>
#include <utility>
#include <MCVector2.h>
#include <iostream>

MCPoint2D::MCPoint2D() :
    x(0),
    y(0)
{
}

MCPoint2D::MCPoint2D(double x_, double y_):
    x(x_),
    y(y_)
{
}

MCPlaneItemType MCPoint2D::type()
{
    return MCPlaneItemType::POINT;
}

void MCPoint2D::setPositionAt(const MCPoint2D &at)
{
    x = at.x;
    y = at.y;
}

void MCPoint2D::move(const MCVector2 &to)
{
    auto m = MCMatrix3::translate(to);
    transform(m);
}

double MCPoint2D::distanceTo(const MCPoint2D &to) const
{
    return sqrtf(std::abs((to.x - x) * (to.x - x))
              + std::abs((to.y - y) * (to.y - y)));
}

void MCPoint2D::transform(const MCMatrix3 &transform)
{
    MCPoint2D res = *this;
    res = res * transform;

    x = res.x;
    y = res.y;
}

void MCPoint2D::scale(double scale)
{
    x *= scale;
    y *= scale;
}

MCPoint2D &MCPoint2D::operator=(const MCPoint2D &rhs)
{
    MCPoint2D copy(rhs);

    std::swap(x, copy.x);
    std::swap(y, copy.y);

    return *this;
}

MCPoint2D &MCPoint2D::operator=(const MCVector2 &rhs)
{
    MCVector2 copy(rhs);

    std::swap(x, copy.x);
    std::swap(y, copy.y);

    return *this;
}

MCPoint2D MCPoint2D::operator+(const MCPoint2D &rhs) const
{
    return MCPoint2D(x + rhs.x, y + rhs.y);
}

MCPoint2D MCPoint2D::operator-(const MCPoint2D &rhs) const
{
    return MCPoint2D(x - rhs.x, y - rhs.y);
}

MCPoint2D MCPoint2D::operator+(const MCVector2 &v) const
{
    return MCPoint2D(x + v.x, y + v.y);
}

MCPoint2D MCPoint2D::operator-(const MCVector2 &v) const
{
    return MCPoint2D(x - v.x, y - v.y);
}

MCPoint2D MCPoint2D::operator*(double scalar) const
{
    return MCPoint2D(x * scalar, y * scalar);
}

MCPoint2D MCPoint2D::operator/(double scalar) const
{
    return MCPoint2D(x / scalar, y / scalar);
}

bool MCPoint2D::operator==(const MCPoint2D &rhs) const
{
    return x == rhs.x && y == rhs.y;
}

bool MCPoint2D::operator!=(const MCPoint2D &rhs) const
{
    return !(this == &rhs);
}

